package com.htl.exampro.base.exception;

import com.htl.exampro.base.model.ServerResponse;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.resource.NoResourceFoundException;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局异常处理器
 */
@Hidden
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(ExamProException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ServerResponse<String> doExamProException(ExamProException e) {
        log.error("【系统异常】{}", e.getMessage(), e);
        return ServerResponse.fail(e);
    }

    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ServerResponse<String> doValidException(MethodArgumentNotValidException argumentNotValidException) {
        BindingResult bindingResult = argumentNotValidException.getBindingResult();
        String errMsg = bindingResult.getFieldErrors().stream().map(o -> o.getDefaultMessage()).collect(Collectors.joining(","));
        log.error(errMsg);
        return ServerResponse.fail(errMsg);
    }

    @ExceptionHandler(value = BindException.class)
    public ServerResponse<String> exceptionHandle(BindException exception) {
        BindingResult result = exception.getBindingResult();
        StringBuilder errorMsg = new StringBuilder();
        List<FieldError> fieldErrors = result.getFieldErrors();
        fieldErrors.forEach(error -> {
            log.error("field: {}, msg:{}", error.getField(), error.getDefaultMessage());
            errorMsg.append(error.getDefaultMessage()).append("!");
        });
        return ServerResponse.fail(errorMsg.toString());
    }

    @ResponseBody
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ServerResponse<String> exception(Exception e) {
        // 放行静态资源异常
        if (e instanceof NoResourceFoundException && e.getMessage().contains("static resource")) {
            return null; // 交由Spring默认处理
        }
        log.error("【系统异常】{}", e.getMessage(), e);
        if ("不允许访问".equals(e.getMessage())) {
            return ServerResponse.fail("没有操作此功能的权限");
        }
        return ServerResponse.fail(CommonError.UNKOWN_ERROR);
    }
}
